#include "catalog.h"

// create a relation named by relation, with attrCnt attributes,
// and the attribute info in attrList
// return OK if everything goes well, otherwise the error name is returned.
const Status RelCatalog::createRel(const string & relation, 
				   const int attrCnt,
				   const attrInfo attrList[])
{
  Status status;
  RelDesc rd;
  AttrDesc ad;

  if (relation.empty() || attrCnt < 1)
    return BADCATPARM;

  if (relation.length() >= sizeof rd.relName)
    return NAMETOOLONG;
 

  // check duplicate and other naming violations
  unsigned int length = 0;
  int offset = 0;
  for (int j = 0; j < attrCnt; j++)
  {
    // if the attribute is too large return error
    if ((attrList[j].attrLen) > MAXSTRINGLEN) return ATTRTOOLONG;
    // if the attrName is too long return error
    if (strlen(attrList[j].attrName) >= sizeof ad.attrName) return NAMETOOLONG;
    length += attrList[j].attrLen;
    // no duplicate attr is allowed in the relation
    for (int k = 0; k < attrCnt; k++)
    {
       if (k == j) break;
       if (strcmp(attrList[j].attrName, attrList[k].attrName) == 0)
       {
         return DUPLATTR;
       }
    }
  }

  status = getInfo(relation, rd);
  // no duplicate relation names is allowed
  if (status == OK) return RELEXISTS;
  if (status != RELNOTFOUND) return status;
  // the total length of attributes should be bounded
  if (length > PAGESIZE) return ATTRTOOLONG;

  // set up relCat
  strcpy(rd.relName, relation.c_str());
  rd.attrCnt = attrCnt;
  status = relCat->addInfo(rd);
  if (status != OK) return status;
  // set up attrCat
  strcpy(ad.relName, relation.c_str()); 
  for (int i = 0; i < attrCnt; i++)
  {      
       strcpy(ad.attrName, attrList[i].attrName);
       ad.attrOffset = offset ;
       ad.attrType = attrList[i].attrType;
       ad.attrLen = attrList[i].attrLen;

       status = attrCat->addInfo(ad);
       if (status != OK) { return status;}
       offset += ad.attrLen;
  }

  status = createHeapFile(relation);
 
  return status;
  


}

